package com.znh.entity;

import com.znh.common.Utils;
import com.znh.enums.PiecePlayerEnum;

import java.awt.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Objects;

/**
 * @version 1.0
 * @Author znh
 * @Date 2024/5/28 上午8:59
 * @注释 行棋记录类
 */
public class Memo implements Serializable {
    /**
     * 当前步骤在全局中属于第几步，同时也是当前节点在树的高度，-1表示未开局（顶级父节点），0表示第一层，以此类推
     */
    private int curStep;
    /**
     * 当前回合轮到谁
     */
    private PiecePlayerEnum curRound;

    /**
     * 行动的棋子
     */
    private Piece actionPiece;

    /**
     * 被吃的棋子，null表示没有棋子被吃
     */
    private Piece atePiece;

    /**
     * 目标坐标
     */
    private Point targetPoint;

    /**
     * 父亲节点
     */
    private Memo parent;

    /**
     * 子节点
     */
    private ArrayList<Memo> children;

    public Memo(int curStep, Memo parent, ArrayList<Memo> children) {
        this.curStep = curStep;
        this.parent = parent;
        this.children = children;
    }

    public Memo(int curStep, PiecePlayerEnum curRound, Memo parent, ArrayList<Memo> children) {
        this.curStep = curStep;
        this.curRound = curRound;
        this.parent = parent;
        this.children = children;
    }

    /**
     * @param curStep     当前步骤在全局中属于第几步，唯一
     * @param curRound    当前回合轮到谁
     * @param actionPiece 行动的棋子
     * @param atePiece    被吃的棋子，null表示没有棋子被吃
     * @param targetPoint 目标坐标
     */
    public Memo(int curStep, PiecePlayerEnum curRound, Piece actionPiece, Piece atePiece, Point targetPoint) {
        this.curStep = curStep;
        this.curRound = curRound;
        this.actionPiece = actionPiece;
        this.atePiece = atePiece;
        this.targetPoint = targetPoint;
    }

    public int getCurStep() {
        return curStep;
    }

    public void setCurStep(int curStep) {
        this.curStep = curStep;
    }

    public PiecePlayerEnum getCurRound() {
        return curRound;
    }

    public void setCurRound(PiecePlayerEnum curRound) {
        this.curRound = curRound;
    }

    public Piece getActionPiece() {
        return actionPiece;
    }

    public void setActionPiece(Piece actionPiece) {
        this.actionPiece = actionPiece;
    }

    public Piece getAtePiece() {
        return atePiece;
    }

    public void setAtePiece(Piece atePiece) {
        this.atePiece = atePiece;
    }

    public Point getTargetPoint() {
        return targetPoint;
    }

    public void setTargetPoint(Point targetPoint) {
        this.targetPoint = targetPoint;
    }

    public Memo getParent() {
        return parent;
    }

    public void setParent(Memo parent) {
        this.parent = parent;
    }

    public ArrayList<Memo> getChildren() {
        return children;
    }

    /**
     * 添加子节点
     * @param childrenNode
     */
    public void addChildren(Memo childrenNode) {
        if (childrenNode==null)return;
        if (children ==null)
        {
            children=new ArrayList<>();
        }
        this.children.add(childrenNode);
        childrenNode.setParent(this);
    }


    public Memo getRoot(){
        if (parent!=null){
            return parent.getRoot();
        }
        return this;
    }

    /**
     * 将一个节点和它的所有子节点的坐标全部翻转
     */
    public void reverse(){
        if (actionPiece!=null){
            actionPiece.reversePoint();
        }
        if (atePiece!=null){
            atePiece.reversePoint();
        }
        if (targetPoint!=null){
            Utils.reversePoint(targetPoint);
        }
        if (children!=null){
            children.forEach(item->{
                item.reverse();
            });
        }
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Memo memo = (Memo) o;
        return curStep == memo.curStep && curRound == memo.curRound && Objects.equals(actionPiece, memo.actionPiece)
                && Objects.equals(atePiece, memo.atePiece) && Objects.equals(targetPoint, memo.targetPoint);
    }

    @Override
    public int hashCode() {
        return Objects.hash(curStep, curRound, actionPiece, atePiece, targetPoint);
    }
}
